package com.greensam.pixelengine.facade.impl;

import cn.hutool.core.bean.BeanUtil;
import com.greensam.pixelengine.exception.BusinessException;
import com.greensam.pixelengine.exception.ThrowUtils;
import com.greensam.pixelengine.facade.SpaceUserFacadeService;
import com.greensam.pixelengine.pojo.base.DeleteRequest;
import com.greensam.pixelengine.pojo.base.PaginationResponse;
import com.greensam.pixelengine.pojo.emuns.ErrorCodeEnum;
import com.greensam.pixelengine.pojo.entity.RolePo;
import com.greensam.pixelengine.pojo.entity.SpacePo;
import com.greensam.pixelengine.pojo.entity.SpaceUserPo;
import com.greensam.pixelengine.pojo.entity.UserPo;
import com.greensam.pixelengine.pojo.query.SpaceUserPageQuery;
import com.greensam.pixelengine.pojo.vo.space.response.SpaceVo;
import com.greensam.pixelengine.pojo.vo.spaceuser.request.SpaceUserCreateRequest;
import com.greensam.pixelengine.pojo.vo.spaceuser.request.SpaceUserEditRequest;
import com.greensam.pixelengine.pojo.vo.spaceuser.request.SpaceUserPageRequest;
import com.greensam.pixelengine.pojo.vo.spaceuser.response.SpaceUserVo;
import com.greensam.pixelengine.service.RoleDataService;
import com.greensam.pixelengine.service.SpaceDataService;
import com.greensam.pixelengine.service.SpaceUserDataService;
import com.greensam.pixelengine.service.UserDataService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Ma Chengrui
 * @since 2025/9/22 16:40
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SpaceUserFacadeServiceImpl implements SpaceUserFacadeService {

    private final UserDataService userDataService;
    private final RoleDataService roleDataService;
    private final SpaceDataService spaceDataService;
    private final SpaceUserDataService spaceUserDataService;

    @Override
    public Long createSpaceUser(SpaceUserCreateRequest request, Long userId) {
        SpacePo spacePo = spaceDataService.getSpaceById(request.getSpaceId())
                .orElseThrow(() -> new BusinessException(ErrorCodeEnum.SpaceNotExist));
        UserPo userPo = userDataService.getUserById(request.getUserId())
                .orElseThrow(() -> new BusinessException(ErrorCodeEnum.UserIsNotExist));
        RolePo rolePo = roleDataService.getRoleById(request.getRoleId())
                .orElseThrow(() -> new BusinessException(ErrorCodeEnum.RoleNotExist));

        SpaceUserPo spaceUser = new SpaceUserPo();
        spaceUser.setCreateBy(userId);
        spaceUser.setUpdateBy(userId);
        spaceUser.setDelete(Boolean.FALSE);
        spaceUser.setSpaceId(request.getSpaceId());
        spaceUser.setSpaceName(spacePo.getName());
        spaceUser.setUserId(request.getUserId());
        spaceUser.setUserName(userPo.getName());
        spaceUser.setRoleId(request.getRoleId());
        spaceUser.setRoleName(rolePo.getName());
        SpaceUserPo save = spaceUserDataService.save(spaceUser);
        log.info("创建空间成员成功：{}", save);
        return save.getId();
    }

    @Override
    public Boolean deleteSpaceUser(DeleteRequest request, Long userId) {
        spaceUserDataService.getSpaceUserById(request.getId()).ifPresent(spaceUser -> {
            spaceUser.setUpdateBy(userId);
            spaceUser.setDelete(Boolean.TRUE);
            spaceUserDataService.save(spaceUser);
        });
        return Boolean.TRUE;
    }

    @Override
    public Boolean editSpaceUser(SpaceUserEditRequest request, Long userId) {
        spaceUserDataService.getSpaceUserByUserId(request.getUserId()).ifPresent(spaceUser -> {
            spaceUser.setUpdateBy(userId);
            roleDataService.getRoleById(request.getRoleId()).ifPresent(rolePo -> {
                spaceUser.setRoleId(rolePo.getId());
                spaceUser.setRoleName(rolePo.getName());
            });
            spaceUserDataService.save(spaceUser);
        });
        return Boolean.TRUE;
    }

    @Override
    public SpaceUserVo getSpaceUser(Long id) {
        ThrowUtils.throwIf(Objects.isNull(id), ErrorCodeEnum.ParamValidError);
        SpaceUserPo spaceUserPo = spaceUserDataService.getSpaceUserById(id)
                .orElseThrow(() -> new BusinessException(ErrorCodeEnum.DataNotExist));
        return SpaceUserVo.spaceUserPo2Vo(spaceUserPo);
    }

    @Override
    public PaginationResponse<SpaceUserVo> pageSpaceUser(SpaceUserPageRequest request) {
        SpaceUserPageQuery query = BeanUtil.copyProperties(request, SpaceUserPageQuery.class);
        PaginationResponse<SpaceUserPo> spaceUserPos = spaceUserDataService.pageSpaceUser(query);
        return spaceUserPos.map(SpaceUserVo::spaceUserPo2Vo);
    }

    @Override
    public List<SpaceUserVo> listMyTeamSpace(Long userId) {
        ThrowUtils.throwIf(Objects.isNull(userId), ErrorCodeEnum.ParamValidError);

        List<SpaceUserPo> spaceUserPos = spaceUserDataService.listSpaceUserByUserId(userId);
        if (spaceUserPos.isEmpty()) {
            return Collections.emptyList();
        }

        // 获取空间信息
        Set<Long> spaceIds = spaceUserPos.stream()
                .map(SpaceUserPo::getSpaceId)
                .collect(Collectors.toSet());
        List<SpacePo> spacePos = spaceDataService.listSpaceByIds(spaceIds);
        Map<Long, SpacePo> spaceIdMap = spacePos.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(SpacePo::getId, Function.identity(), (existing, replacement) -> existing));

        return spaceUserPos.stream()
                .map(po -> {
                    SpaceUserVo spaceUserVo = SpaceUserVo.spaceUserPo2Vo(po);
                    SpacePo space = spaceIdMap.getOrDefault(po.getSpaceId(), null);
                    if (Objects.nonNull(space)) {
                        SpaceVo spaceVo = SpaceVo.spacePo2Vo(space);
                        Objects.requireNonNull(spaceUserVo).setSpace(spaceVo);
                    }
                    return spaceUserVo;
                })
                .toList();
    }
}
